//
//  StatusesListViewModel.swift
//  SinaMicroBlog
//
//  Created by wxy on 15/9/7.
//  Copyright © 2015年 wxy. All rights reserved.
//

import UIKit
import ReactiveCocoa
import SDWebImage

// 微博列表视图模型 - 分离网络方法
class StatusesListViewModel: NSObject {
    
    /// 微博数据数组 - 项目名称不能有'中文+数字'组成
    // 懒加载
    lazy var statuses = [StatusesViewModel]()
    
    // since_id 第一项 max_id 最后一项
    
    /// 加载微博数据
    ///
    /// - parameter isPullUpResfresh: 是否上拉刷新标记
    ///
    /// - returns: RACSignal
    func loadStatuses(isPullUpResfresh isPullUpResfresh: Bool) -> RACSignal {
        
        // TODO: 这里还是稍微有点不明白
        
        // 初始刷新：statuses 数组中没有内容
        // 下拉刷新：取 statuses 的第一项的 id 为 since_id
        var since_id = statuses.first?.statuses.id ?? 0
        
        // 上拉刷新：取 statuses 数组最后一项 id 为 max_id
        var max_id = 0
        // 如果上拉刷新
        if isPullUpResfresh {
            
            since_id = 0
            max_id = statuses.first?.statuses.id ?? 0
        }
        // RACSignal 在订阅的时候，会对 self 进行强引用，sendCompleted 说明信号完成，会释放对 self 的强引用
        // 以下代码不存在循环引用，但是为了保险，可以使用 [weak self] 防范！
        return RACSignal.createSignal({ [weak self] (subscriber) -> RACDisposable! in
            
            // 网络工具，执行的时候，会对 self 进行强引用，网络访问结束后，后对 self 的引用释放！
            NetworkTools.sharedNetworkTools.loadStatuses(since_id: since_id, max_id: max_id).subscribeNext({ (result) -> Void in
                
                //printLog(result)
                
                // 1.获取result中的statuses 字典数组
                guard let array = result["statuses"] as? [[String:AnyObject]] else {
                    
                    subscriber.sendError(NSError(domain: "com.wing.error", code: -250, userInfo: ["errorMessage": "没有正确数据"]))
                    return
                }
                
                // 2.字典转模型
                // 定义并创建一个临时数组 记录当前网络请求返回的结果
                var mtArray = [StatusesViewModel]()
                
                // 遍历数组
                for dict in array {
                    
                    mtArray.append(StatusesViewModel(statuses: Statuses(dict: dict)))
                }
                
                // printLog("刷新到 \(mtArray.count) 条微博")
                
                // 添加尾随闭包
                self?.cacheWebImage(mtArray) {
                    
                    if max_id > 0 {
                        
                        // 将新数据加载到原来的数据末尾
                        self?.statuses += mtArray
                        
                    } else {
                        
                        // 下拉刷新
                        self?.statuses = mtArray + self!.statuses
                    }
                    
                    // 如果下拉刷新 提示用户
                    if since_id > 0 {
                        
                        // RAC 是 OC 的 通知订阅者 下拉刷新数据
                        subscriber.sendNext(mtArray.count)
                    }
                    
                    // 3.通知调用方,数据加载完成
                    subscriber.sendCompleted()
                }
                
                
                
                }, error: { (error) -> Void in
                    
                    subscriber.sendError(error)
                }) { () -> Void in
                    
                    printLog("加载数据完成")
            }
            
            return nil
        })
    }
    
    /// 缓存单张网络图片
    ///
    /// - parameter array:    视图模型数组
    /// - parameter finished: 缓存完成回调
    private func cacheWebImage(array: [StatusesViewModel], finished: () -> ()) {
        
        // 1.创建调度组(同时下载缓存多张图片) 与第三方框架使用 不用考虑线程和队列
        let group = dispatch_group_create()
        
        // 记录图片大小
        var dataLength = 0
        
        // 遍历视图模型数组
        for viewModel in array {
            
            // 目标：只需要缓存单张图片
            let count = viewModel.thumbnailURLs?.count ?? 0
            
            if count != 1 {
                continue
            }
            
            // printLog(viewModel.thumbnailURLs)
            // 2.入组 紧贴着block/闭包 enter&leave 成对出现
            dispatch_group_enter(group)
            
            // 使用SDWebImage核心函数下载图片
            SDWebImageManager.sharedManager().downloadImageWithURL(viewModel.thumbnailURLs![0], options: [], progress: nil, completed: { (image, _, _, _, _) -> Void in
                
                // URL不一定有图片 也能进入到这里进行回调
                if image != nil {
                    // 将 image 转换成二进制数据
                    let data = UIImagePNGRepresentation(image)
                    
                    dataLength += data?.length ?? 0
                }
                
            })
            // 3.出组
            dispatch_group_leave(group)
        }
        
        // 4.调度组监听
        dispatch_group_notify(group, dispatch_get_main_queue()) { () -> Void in
            
            printLog("缓存图片完成\(dataLength / 1024) K")
            
            // 执行闭包
            finished()
        }
    }

}
